<script setup lang="ts">
import { UploadFilled } from '@element-plus/icons-vue'
import type { CustomDialogInstance } from '@/types'
import { carbonInventoryApi } from '@/api'
import { TANPANCHA_DATA_SOURCE_TYPE, TANPANCHA_DATA_FILL_TYPE } from '@/constant/modules/tanpancha'
import { ClickOutside as vClickOutside } from 'element-plus'
import { cloneDeep } from 'lodash-es'
import RealNumberInput from '@/components/RealNumberInput/index.vue'

defineOptions({ name: 'AsyncTableData' })

const props = defineProps<{
  carbonInventoryId: number
  readonly?: boolean
  filterName?: string
  filterEntryMethod?: TANPANCHA_DATA_FILL_TYPE
  filterSourceType?: TANPANCHA_DATA_SOURCE_TYPE
}>()
const emit = defineEmits<{
  (e: 'uploadSuccess'): void
  (e: 'deleteSuccess'): void
}>()

const tanpanchaStore = useTanpanchaStore()
const dialogRef = ref<CustomDialogInstance>()
const loading = ref(false)
const list = ref<any>([])
const fileList = shallowRef<any>([])
const rowFileList = shallowRef<any>([])
const currentRow = shallowRef<any>()

const popoverShows = ref<boolean[]>([])

function isEmpty(val: any) {
  return val === undefined || val === null || val === ''
}

const filterList = computed(() => {
  return cloneDeep(list.value.filter((item: any) => {
    return (
      (!props.filterName || item.name.includes(props.filterName))
      && (isEmpty(props.filterEntryMethod) || item.entryMethod === props.filterEntryMethod)
      && (isEmpty(props.filterSourceType) || item.sourceType === props.filterSourceType)
    )
  }))
})

async function handleInputBlur(row: any, key: keyof typeof row, value: number | null) {
  // console.log('blur: ', value)
  row[key] = value
  const isEmpty = (value: any) => (value === null || value === undefined || value === '')
  // await nextTick()
  const isYear = row.entryMethod === TANPANCHA_DATA_FILL_TYPE.YEAR
  if (isYear) { // 年度填报
    // 填了年度值，并把年度值 / 12，余值加入到 1月份
    if (value === 0 || value === null || isEmpty(value)) {
      row.januaryNum
      = row.februaryNum
      = row.marchNum
      = row.aprilNum
      = row.mayNum
      = row.juneNum
      = row.julyNum
      = row.augustNum
      = row.septemberNum
      = row.octoberNum
      = row.novemberNum
      = row.decemberNum
      = value
    }
    else {
      row.januaryNum
      = row.februaryNum
      = row.marchNum
      = row.aprilNum
      = row.mayNum
      = row.juneNum
      = row.julyNum
      = row.augustNum
      = row.septemberNum
      = row.octoberNum
      = row.novemberNum
      = row.decemberNum = Math.floor(value / 12)

      let s = `${Math.round((value % 12 + Number.EPSILON) * 1e6) / 1e6 + row.januaryNum}`
      const [integerPart, decimalPart] = s.split('.')
      if (decimalPart) {
        s = `${integerPart}.${decimalPart.slice(0, 6)}`
      }
      row.januaryNum = s
    }
  }
  else { // 月度填报
    // 填了月份，把各个月份累加汇到年度值上
    // 但是相加可能存在精度问题（小数点后很多位）
    // 确保接近准确值
    const sum = (Number(row.januaryNum)
      + Number(row.februaryNum)
      + Number(row.marchNum)
      + Number(row.aprilNum)
      + Number(row.mayNum)
      + Number(row.juneNum)
      + Number(row.julyNum)
      + Number(row.augustNum)
      + Number(row.septemberNum)
      + Number(row.octoberNum)
      + Number(row.novemberNum)
      + Number(row.decemberNum)
      + Number.EPSILON)
    let s = `${Math.round(sum * 1e6) / 1e6}`
    const [integerPart, decimalPart] = s.split('.')
    if (decimalPart) {
      s = `${integerPart}.${decimalPart.slice(0, 6)}`
    }
    const a = Number.parseFloat(s)
    if (Number.isNaN(a)) {
      row.yearNum = 0
    }
    else {
      row.yearNum = a
    }
  }
}

async function getList() {
  loading.value = true
  try {
    const { data } = await carbonInventoryApi.queryCarbonInventoryDataEntryInfo(props.carbonInventoryId)
    list.value = data ?? []
    popoverShows.value = data.map(() => false)
  }
  catch (error) {
    console.error(error)
  }
  finally {
    loading.value = false
  }
}

async function clickConfirm(done: () => void) {
  if (!unref(currentRow))
    return
  const rqs: any = []
  fileList.value.forEach((v: any) => {
    rqs.push(carbonInventoryApi.uploadCarbonInventoryDataEntryFile(
      currentRow.value.activityId as number,
      v.raw,
    ))
  })
  Promise.all(rqs).then(() => {
    ElMessage.success('上传成功！')
    done()
    closeUploadModal()
    fileList.value = []
    emit('uploadSuccess')
  }).finally(() => {
    done()
  })
}

async function openUploadModal() {
  dialogRef.value?.open()
}

async function closeUploadModal() {
  dialogRef.value?.close()
}

async function handleClickUpload(item: any) {
  currentRow.value = item
  await nextTick()
  openUploadModal()
}
async function handleClickView(item: any, index: number) {
  carbonInventoryApi.queryCarbonInventoryDataEntryFileList(item.activityId)
    .then(({ data }) => {
      rowFileList.value = data ?? []
      if (data.length === 0) {
        ElMessage.warning('暂无凭证！')
      }
      for (let i = 0; i < popoverShows.value.length; i++) {
        popoverShows.value.splice(i, 1, (index === i && data.length > 0))
      }
    })
}

async function handleDeleteFileById(id: number) {
  const res = await ElMessageBox.confirm(
    '该操作将永久删除该数据，确定删除？',
    '操作提示',
    {
      type: 'warning',
    },
  ).catch(e => e)
  if (res === 'confirm') {
    carbonInventoryApi.deleteCarbonInventoryDataEntryFileById(id)
      .then(() => {
        ElMessage.success('删除成功！')
        emit('deleteSuccess')
      })
  }
}

onMounted(async () => {
  // console.log('async table mounted')
  await getList()
})
onUnmounted(() => {
  // console.log('async table unmounted')
})
defineExpose({
  getData() {
    return filterList.value
  },
})
</script>

<template>
  <div class="fake flex-auto overflow-auto p-3">
    <ElTable v-loading="loading" :data="filterList" element-loading-custom-class="global-loading" border height="100%">
      <ElTableColumn prop="name" label="设施/活动名称" :min-width="150" fixed />
      <ElTableColumn prop="entryMethod" label="填报方式" fixed :min-width="100">
        <template #default="{ row }">
          {{ tanpanchaStore.getDataFillTypeText(row.entryMethod) }}
        </template>
      </ElTableColumn>
      <ElTableColumn prop="sourceType" label="活动数据来源" :min-width="150" fixed>
        <template #default="{ row }">
          {{ tanpanchaStore.getSourceTypeText(row.sourceType) }}
        </template>
      </ElTableColumn>
      <ElTableColumn prop="yearNum" label="年总值" fixed :min-width="200">
        <template v-if="!readonly && filterSourceType !== TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC" #default="{ row }">
          <RealNumberInput
            v-if="TANPANCHA_DATA_FILL_TYPE.YEAR === row.entryMethod"
            :initial-value="row.yearNum"
            @blur="handleInputBlur(row, 'yearNum', $event)"
          />
          <span v-else>{{ row.yearNum }}</span>
        </template>
      </ElTableColumn>
      <ElTableColumn prop="januaryNum" label="1月" :min-width="200">
        <template v-if="!readonly && filterSourceType !== TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC" #default="{ row }">
          <span v-if="TANPANCHA_DATA_FILL_TYPE.YEAR === row.entryMethod || row.sourceType === TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC">{{ row.januaryNum }}</span>
          <RealNumberInput
            v-else
            :initial-value="row.januaryNum"
            @blur="handleInputBlur(row, 'januaryNum', $event)"
          />
        </template>
      </ElTableColumn>
      <ElTableColumn prop="februaryNum" label="2月" :min-width="200">
        <template v-if="!readonly && filterSourceType !== TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC" #default="{ row }">
          <span v-if="TANPANCHA_DATA_FILL_TYPE.YEAR === row.entryMethod || row.sourceType === TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC">{{ row.februaryNum }}</span>
          <RealNumberInput
            v-else
            :initial-value="row.februaryNum"
            @blur="handleInputBlur(row, 'februaryNum', $event)"
          />
        </template>
      </ElTableColumn>
      <ElTableColumn prop="marchNum" label="3月" :min-width="200">
        <template v-if="!readonly && filterSourceType !== TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC" #default="{ row }">
          <span v-if="TANPANCHA_DATA_FILL_TYPE.YEAR === row.entryMethod || row.sourceType === TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC">{{ row.marchNum }}</span>
          <RealNumberInput
            v-else
            :initial-value="row.marchNum"
            @blur="handleInputBlur(row, 'marchNum', $event)"
          />
        </template>
      </ElTableColumn>
      <ElTableColumn prop="aprilNum" label="4月" :min-width="200">
        <template v-if="!readonly && filterSourceType !== TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC" #default="{ row }">
          <span v-if="TANPANCHA_DATA_FILL_TYPE.YEAR === row.entryMethod || row.sourceType === TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC">{{ row.aprilNum }}</span>
          <RealNumberInput
            v-else
            :initial-value="row.aprilNum"
            @blur="handleInputBlur(row, 'aprilNum', $event)"
          />
        </template>
      </ElTableColumn>
      <ElTableColumn prop="mayNum" label="5月" :min-width="200">
        <template v-if="!readonly && filterSourceType !== TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC" #default="{ row }">
          <span v-if="TANPANCHA_DATA_FILL_TYPE.YEAR === row.entryMethod || row.sourceType === TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC">{{ row.mayNum }}</span>
          <RealNumberInput
            v-else
            :initial-value="row.mayNum"
            @blur="handleInputBlur(row, 'mayNum', $event)"
          />
        </template>
      </ElTableColumn>
      <ElTableColumn prop="juneNum" label="6月" :min-width="200">
        <template v-if="!readonly && filterSourceType !== TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC" #default="{ row }">
          <span v-if="TANPANCHA_DATA_FILL_TYPE.YEAR === row.entryMethod || row.sourceType === TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC">{{ row.juneNum }}</span>
          <RealNumberInput
            v-else
            :initial-value="row.juneNum"
            @blur="handleInputBlur(row, 'juneNum', $event)"
          />
        </template>
      </ElTableColumn>
      <ElTableColumn prop="julyNum" label="7月" :min-width="200">
        <template v-if="!readonly && filterSourceType !== TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC" #default="{ row }">
          <span v-if="TANPANCHA_DATA_FILL_TYPE.YEAR === row.entryMethod || row.sourceType === TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC">{{ row.julyNum }}</span>
          <RealNumberInput
            v-else
            :initial-value="row.julyNum"
            @blur="handleInputBlur(row, 'julyNum', $event)"
          />
        </template>
      </ElTableColumn>
      <ElTableColumn prop="augustNum" label="8月" :min-width="200">
        <template v-if="!readonly && filterSourceType !== TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC" #default="{ row }">
          <span v-if="TANPANCHA_DATA_FILL_TYPE.YEAR === row.entryMethod || row.sourceType === TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC">{{ row.augustNum }}</span>
          <RealNumberInput
            v-else
            :initial-value="row.augustNum"
            @blur="handleInputBlur(row, 'augustNum', $event)"
          />
        </template>
      </ElTableColumn>
      <ElTableColumn prop="septemberNum" label="9月" :min-width="200">
        <template v-if="!readonly && filterSourceType !== TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC" #default="{ row }">
          <span v-if="TANPANCHA_DATA_FILL_TYPE.YEAR === row.entryMethod || row.sourceType === TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC">{{ row.septemberNum }}</span>
          <RealNumberInput
            v-else
            :initial-value="row.septemberNum"
            @blur="handleInputBlur(row, 'septemberNum', $event)"
          />
        </template>
      </ElTableColumn>
      <ElTableColumn prop="octoberNum" label="10月" :min-width="200">
        <template v-if="!readonly && filterSourceType !== TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC" #default="{ row }">
          <span v-if="TANPANCHA_DATA_FILL_TYPE.YEAR === row.entryMethod || row.sourceType === TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC">{{ row.octoberNum }}</span>
          <RealNumberInput
            v-else
            :initial-value="row.octoberNum"
            @blur="handleInputBlur(row, 'octoberNum', $event)"
          />
        </template>
      </ElTableColumn>
      <ElTableColumn prop="novemberNum" label="11月" :min-width="200">
        <template v-if="!readonly && filterSourceType !== TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC" #default="{ row }">
          <span v-if="TANPANCHA_DATA_FILL_TYPE.YEAR === row.entryMethod || row.sourceType === TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC">{{ row.novemberNum }}</span>
          <RealNumberInput
            v-else
            :initial-value="row.novemberNum"
            @blur="handleInputBlur(row, 'novemberNum', $event)"
          />
        </template>
      </ElTableColumn>
      <ElTableColumn prop="decemberNum" label="12月" :min-width="200">
        <template v-if="!readonly && filterSourceType !== TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC" #default="{ row }">
          <span v-if="TANPANCHA_DATA_FILL_TYPE.YEAR === row.entryMethod || row.sourceType === TANPANCHA_DATA_SOURCE_TYPE.AUTOMITIC">{{ row.decemberNum }}</span>
          <RealNumberInput
            v-else
            :initial-value="row.decemberNum"
            @blur="handleInputBlur(row, 'decemberNum', $event)"
          />
        </template>
      </ElTableColumn>
      <ElTableColumn prop="q" label="凭证管理" fixed="right" :min-width="150">
        <template #default="{ row, $index }">
          <ElLink v-if="!readonly" class="free" type="success" :underline="false" @click="handleClickUpload(row)">
            上传
          </ElLink>
          <ElPopover
            :visible="popoverShows[$index]" placement="left-start" trigger="click"
            :width="300"
          >
            <template #reference>
              <ElLink class="free ml-2" type="warning" :underline="false" @click="handleClickView(row, $index)">
                查看
              </ElLink>
            </template>
            <div v-click-outside="() => { popoverShows[$index] = false }">
              <div v-for="item in rowFileList" :key="item.id" class="w-full flex items-center p-3">
                <div :title="item.fileName" :class="{ 'max-w-44': !readonly }" class="overflow-hidden text-ellipsis whitespace-nowrap opacity-80">
                  <a :href="item.fileUrl" target="_blank">{{ item.fileName }}</a>
                </div>
                <ElLink v-if="!readonly" class="ml-auto" type="danger" :underline="false" @click="handleDeleteFileById(item.id)">
                  删除
                </ElLink>
              </div>
            </div>
          </ElPopover>
        </template>
      </ElTableColumn>
    </ElTable>

    <CustomDialog
      ref="dialogRef"
      title="上传凭证" width="640px"
      need-saving
      confirm-button-text="开始上传"
      @confirm="clickConfirm"
    >
      <ElUpload
        v-model:file-list="fileList"
        drag action="#" :auto-upload="false"
        multiple
      >
        <ElIcon class="el-icon--upload">
          <UploadFilled />
        </ElIcon>
        <div class="el-upload__text">
          拖动文件到这里 或者 <em>点击这里选择文件</em>
        </div>
        <template #tip>
          <div class="el-upload__tip fs-12 opacity-60">
            提示：支持多选
          </div>
        </template>
      </ElUpload>
    </CustomDialog>
  </div>
</template>

<style>
.fake .el-table .el-input:not(.el-pagination__editor):not(.free) {
  min-width: auto !important;
  width: auto !important;
}
</style>
